package org.proddevplm.servlets;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.proddevplm.dao.util.EntityBuilder;
import org.proddevplm.dao.util.HibernateUtil;


public class CommonsFileUploadServlet extends HttpServlet {
    private static final String TMP_DIR_PATH = ".//..//";
    private File tmpDir;
    private static final String DESTINATION_DIR_PATH = ".//..//..//uploads//";
    private File destinationDir;
    private String filePath;
    private static final int BUFSIZE = 4 * 1024;

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        tmpDir = new File(TMP_DIR_PATH);
        if (!tmpDir.isDirectory()) {
            throw new ServletException(TMP_DIR_PATH + " is not a directory");
        }
        String realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH);
        destinationDir = new File(realPath);
        if (!destinationDir.isDirectory()) {
            throw new ServletException(DESTINATION_DIR_PATH + " is not a directory");
        }

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


        Boolean sucesfullOperation = false;
        Map fieldsMap = null;
        String type = null;

        DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
        /*
           *Set the size threshold, above which content will be stored on disk.
           */
        fileItemFactory.setSizeThreshold(10 * 1024 * 1024); //10 MB
        /*
           * Set the temporary directory to store the uploaded files of size above threshold.
           */
        fileItemFactory.setRepository(tmpDir);
        ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory);
        try {
            /*
			 * Parse the request
			 */
            List items = uploadHandler.parseRequest(request);
            Iterator itr = items.iterator();
            fieldsMap = new HashMap(items.size());
            while (itr.hasNext()) {
                FileItem item = (FileItem) itr.next();
                /*
                     * Handle Form Fields.
                     */
                if (item.isFormField()) {
                    if ("type".equals(item.getFieldName())) {
                        type = item.getString();
                    }
                    fieldsMap.put(item.getFieldName(), item.getString());
                } else if (item.getName()!=null && !"".equals(item.getName())) {                
                    File file = new File(destinationDir, item.getName());                    
                    item.write(file);
                    fieldsMap.put("filePath", file.getAbsolutePath());
                }
                
            }
            sucesfullOperation = true;

        } catch (FileUploadException ex) {
            ex.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        if (sucesfullOperation && type != null) {
            try {
                HibernateUtil.currentSession().beginTransaction();
                HttpSession session = request.getSession();
                Object entity = EntityBuilder.buildEntity(type, fieldsMap, session);
                HibernateUtil.currentSession().merge(entity);
                HibernateUtil.currentSession().getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            if (!sucesfullOperation) {
                System.out.print("Upload operation was not sucesfull. Please contact the administrator");
            } else {
                System.out.print("Debug: Type parameter is null. Please check form data");
            }
        }

        
        response.sendRedirect("/proddev/pages/index.jsp");
    }
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    	throws ServletException, java.io.IOException {
    	
    	try {
            HibernateUtil.currentSession().beginTransaction();
            
            String fileName = request.getParameter("fileName");
            File f = new File(destinationDir + "\\"+ fileName);
                        
            int length = 0;
            ServletOutputStream op = response.getOutputStream();
            ServletContext context = getServletConfig().getServletContext();
            String mimetype = context.getMimeType(fileName);

            //  Set the response and go!

            response.setContentType((mimetype != null) ? mimetype : "application/octet-stream");
            response.setContentLength((int) f.length());
            response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

            //  Stream to the requester.

            byte[] bbuf = new byte[BUFSIZE];
            DataInputStream in = new DataInputStream(new FileInputStream(f));

            while ((in != null) && ((length = in.read(bbuf)) != -1)) {
                op.write(bbuf, 0, length);
            }

            in.close();
            op.flush();
            op.close();
            
    	}catch(Exception e){

        } finally {
            HibernateUtil.currentSession().getTransaction().commit();
        }
    }

}